package cn.how2j.trend.service;

import cn.how2j.trend.pojo.Index;
import cn.how2j.trend.util.SpringContextUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * @author LiGang
 * @version 1.0
 * @date 2021/4/8 10:11
 */

@Service
@CacheConfig(cacheNames = "indexes")
public class IndexService {

    private List<Index> indexes;

    @Autowired
    RestTemplate restTemplate;

    /**
     * 刷新数据.这里用了 SpringContextUtil.getBean 去重新获取了一次 IndexService，为什么不直接在 fresh 方法里调用 remove, store 方法， 而要重新获取一次呢？
     * 这个是因为 springboot 的机制大概有这么个 bug吧. 从已经存在的方法里调用 redis 相关方法，并不能触发 redis 相关操作，所以只好用这种方式重新获取一次了。
     * @return 返回刷新的数据
     *
     */
    @HystrixCommand(fallbackMethod = "thirdPartNotConnected")
    public List<Index> fresh() {
        indexes =fetchIndexesFromThirdPart();
        IndexService indexService = SpringContextUtil.getBean(IndexService.class);
        indexService.remove();
        return indexService.store();
    }

    /**
     * 清空数据
     */
    @CacheEvict(allEntries=true)
    public void remove(){
    }

    /**
     * 从 redis 中获取数据
     * @return 缓存数据
     */
    @Cacheable(key="'all_codes'")
    public List<Index> get(){
        return CollUtil.toList();
    }

    /**
     * 保存数据
     * @return indexes成员变量
     */
    @Cacheable(key="'all_codes'")
    public List<Index> store(){
        return indexes;
    }

    /**
     * @return 返回第三方数据
     */
    public List<Index> fetchIndexesFromThirdPart() {
        List<Map> temp = restTemplate.getForObject("http://127.0.0.1:8090/indexes/codes.json", List.class);
        return map2Index(temp);
    }

    public List<Index> thirdPartNotConnected() {
        System.out.println("third_part_not_connected()");
        Index index = new Index();
        index.setCode("000000");
        index.setName("无效指数代码");
        return CollectionUtil.toList(index);
    }

    private List<Index> map2Index(List<Map> temp) {
        List<Index> indexes = new ArrayList<>();
        for (Map map : temp) {
            String code = map.get("code").toString();
            String name = map.get("name").toString();
            Index index = new Index();
            index.setCode(code);
            index.setName(name);
            indexes.add(index);
        }

        return indexes;
    }

}